Skip to content

SupernodalLU: route panel triangular solves through TriangularSolve (−13 to −18% refactorization)#1113

Merged
ChrisRackauckas merged 1 commit into
SciML:mainfrom
ChrisRackauckas-Claude:supernodal-lu-trsm
Jul 26, 2026
Merged

SupernodalLU: route panel triangular solves through TriangularSolve (−13 to −18% refactorization)#1113
ChrisRackauckas merged 1 commit into
SciML:mainfrom
ChrisRackauckas-Claude:supernodal-lu-trsm

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

⚠️ Draft — please ignore until reviewed by @ChrisRackauckas.

Independent of #1109, #1111 and #1112; touches src/SupernodalLU/numeric.jl (two hooks), the RecursiveFactorization extension, and 3 lines of Project.toml.

What

The supernodal factorization applies two BLAS-3 trsms per supernode against its just-factored diagonal block — the L21 panel on the right by U11, the U12 panel on the left by unit-L11. These now go through overridable hooks whose default is the stdlib triangular solve, with LinearSolveRecursiveFactorizationExt overriding them with TriangularSolve.

Why this costs nothing

TriangularSolve is a hard dependency of RecursiveFactorization and is what RecursiveFactorization uses for its own trsms internally. It is declared here as a weakdep purely to trigger the extension; because RecursiveFactorization pulls it in transitively, using RecursiveFactorization alone still activates everything — no user gains an install. That is also exactly the condition under which RFLUFactorization becomes the dense default, so the sparse solver's panel work and the dense default end up on the same kernels.

(This recovers the gap I flagged when the diagonal-block factorization moved to LinearSolve's dense init/solve!: that move was performance-neutral on its own, and the ~15 % that had been attributed to it was in fact the panel trsms.)

Measured (refactorization, BLAS pinned to 1 thread)

matrix stdlib trsm TriangularSolve change
poisson2d_512 0.4781 s 0.3921 s −18 %
poisson3d_32 0.3466 s 0.3027 s −13 %

Residuals unchanged (1.5e-14 / 8.8e-16). Verified the extension actually loads and takes the override path in an environment with RecursiveFactorization present.

GROUP=Core passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_017rr42T1vFRRT8D7DMAmJzf

The supernodal factorization applies two BLAS-3 trsms per supernode
against its just-factored diagonal block: the L21 panel on the right by
U11, and the U12 panel on the left by unit-L11. They now go through
overridable hooks whose default is the stdlib triangular solve, with
LinearSolveRecursiveFactorizationExt overriding them with
TriangularSolve.

TriangularSolve is a hard dependency of RecursiveFactorization and is
what RecursiveFactorization uses for its own trsms, so this adds nothing
to anyone's dependency graph: it is declared as a weakdep purely to
trigger the extension, and since RecursiveFactorization pulls it in,
loading RecursiveFactorization alone still activates everything. That is
also exactly the condition under which RFLUFactorization becomes the
dense default, so the sparse solver's panel work and the dense default
run on the same kernels.

Measured refactorization, BLAS pinned to 1 thread:

  poisson2d_512  0.4781 -> 0.3921 s  (-18%)
  poisson3d_32   0.3466 -> 0.3027 s  (-13%)

Residuals unchanged (1.5e-14 / 8.8e-16).

GROUP=Core passes.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ChrisRackauckas
ChrisRackauckas marked this pull request as ready for review July 26, 2026 10:06
@ChrisRackauckas
ChrisRackauckas merged commit a39171d into SciML:main Jul 26, 2026
62 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants